<?php
#
# dmBridge: a data access framework for CONTENTdm(R)
#
# Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher
# Education, on behalf of the University of Nevada, Las Vegas
#

/**
 * Handles vocabulary suggestions and frequency mappings.
 *
 * @author Alex Dolski <alex.dolski@unlv.edu>
 * @license http://www.opensource.org/licenses/mit-license.php
 */
class DMAPIVocabularyController extends DMAbstractController {

	/**
	 * @param string alias_fields Comma-separated alias and list of field nicks
	 */
	public function frequency($alias_fields) {
		$response = new DMHTTPResponse();
		$rep = DMHTTPResponseFactory::getRepresentation();
		$trans = DMHTTPResponseFactory::getTransformer();
		$response->setRepresentation($rep);

		$field_nicks = explode(",", $alias_fields);
		$alias = "/" . trim(array_shift($field_nicks), "/");
		$alias = DMCollection::getSanitizedAlias($alias);
		$collection = DMCollectionFactory::getCollection($alias);

		$fields = array();
		foreach ($field_nicks as $f) {
			$f = substr(DMString::paranoid($f), 0, 10);
			if (!$collection->getField($f)) {
				$response->setStatusCode(404);
				$rep->setBody(sprintf(
						"Field %s not available in collection %s.",
						$f, $alias));
				$response->send();
			}
			$fields[] = new DMDCElement($f);
		}

		$terms = array();
		$limit = 1024;

		// grab the first page of results
		$results = dmQuery(array($alias), $terms, $field_nicks,
			null, $limit, 1, $total, 1);

		$vocab = array();
		// loop through each page of results; this is horribly expensive but
		// there is no alternative
		for ($i = $limit; $i < $total + $limit; $i = $i + $limit) {
			if ($i > $limit) { // if 2nd iteration
				$results = dmQuery(array($alias), $terms, $field_nicks,
				null, $limit, $i - $maxresults, $total, 1);
			}
			// compile all unique terms in the $vocab array
			foreach ($fields as $f) {
				foreach ($results as $r) {
					if (!in_array($f->getNick(), array_keys($r))) {
						continue;
					}
					if (!$r[$f->getNick()]) {
						continue; // ignore empty fields
					}
					// split up semicolon-separated terms
					$tmp = explode("; ", $r[$f->getNick()]);
					foreach ($tmp as &$t) {
						$t = rtrim(trim($t), ".,;");
						if (!$t) {
							unset($t);
						}
					}
					$vocab = array_merge($vocab, $tmp);
				}
			}
		}

		$counts = array_count_values($vocab);
		arsort($counts, SORT_NUMERIC);

		$rep->setBody($trans->transformVocabularyFrequencies($counts));
		$response->send();
		die;
	}

	/**
	 * Requires an array of field nicks passed as a GET variable, e.g.
	 * &nicks[]=title, as well as a term string which can be either a GET or
	 * POST variable (GET will take precedence), e.g. &term=cats.
	 *
	 * @return array
	 * @since 0.1
	 */
	public function suggest() {
		$response = new DMHTTPResponse();
		$rep = DMHTTPResponseFactory::getRepresentation();
		$trans = DMHTTPResponseFactory::getTransformer();
		$response->setRepresentation($rep);

		$uri = DMHTTPRequest::getCurrent()->getURI();
		$alias = $term = null;
		$nicks = array();

		if ($uri->getQueryValue("CISOROOT")
				&& $uri->getQueryValue("CISOBOX1")) {
			$alias = DMCollection::getSanitizedAlias(
					$uri->getQueryValue("CISOROOT"));
			$term = DMString::paranoid(
				substr($uri->getQueryValue("CISOBOX1"), 0, 100),
					array('-', ':', ',', '.'));
			foreach ($uri->getQuery() as $kv) {
				if (strpos($kv['key'], "CISOFIELD") !== false) {
					$nicks[] = $kv['value'];
				}
			}
		}

		if (!count($nicks) || !$alias || !$term) {
			$response->setStatusCode(400);
			$rep->setBody("Invalid parameters.");
			$response->send();
			die;
		}

		$col = DMCollectionFactory::getCollection($alias);

		$fields = array();
		foreach ($nicks as $n) {
			$f = new DMDCElement(DMString::paranoid(substr($n, 0, 6)));
			$f->setCollection($col);
			$fields[] = $f;
		}

		$suggestions = array();
		foreach ($fields as $f) {
			foreach ($f->getVocabulary() as $v) {
				if (stripos($v, substr($term, 0, 100)) === 0) {
					$suggestions[] = $v;
				}
			}
		}

		$rep->setBody($trans->transformVocabularySuggestions($suggestions));
		$response->send();
		die;
	}

}
